package com.example.lvzhaobing.bluetooth;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelUuid;
import android.os.SystemClock;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.appindexing.Thing;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.server.converter.StringToIntConverter;

import java.io.InputStream;
import java.sql.Time;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static android.R.attr.data;
import static android.R.attr.factor;
import static android.R.attr.handle;
import static android.R.attr.lines;
import static android.R.id.message;


@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class MainActivity extends AppCompatActivity implements CompoundButton.OnCheckedChangeListener {
    int length_2 = 2;
    int length_8 = 8;
    int length_16 = 16;
    int length_32 = 32;

    //发送计数
    private int sendbytes_count;
    //将要发送的数据计数
    private int bytes_count;

    private List<BluetoothDevice> deviceList = new ArrayList<>();
    private BluetoothAdapter bluetoothAdapter;
    private BluetoothGatt bluetoothGatt;
    private BluetoothGattCharacteristic mCharacteristic;
    private ArrayList<Item> data;
    private MyAdapter adapter;
    private Context context;
    private boolean mScanning;
    private BluetoothDevice device;
    //这里的REQUEST_ENABLE_BT也就是一个回调的标志
    public static final int REQUEST_ENABLE_BT = 0;
    //服务列表
    List<BluetoothGattService> supportedGattServices;
    //特征值列表
    List<BluetoothGattCharacteristic> listGattCharacteristic;
    BluetoothGattService service;
    BluetoothGattCharacteristic characteristic;

    //定义一个ListView
    private ListView listView = null;
    private Switch switchButton = null;
    private Button sendButton=null;
    private EditText editText=null;
    private ImageView imageView=null;
    private ImageView refreshButton=null;
    /**
     * ATTENTION: This was auto-generated to implement the App Indexing API.
     * See https://g.co/AppIndexing/AndroidStudio for more information.
     */
    private GoogleApiClient client;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initBT();

        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
    }

    private void initView() {
        data = new ArrayList<Item>();
        //获取控件
        listView = (ListView) findViewById(R.id.listView);
        switchButton = (Switch) findViewById(R.id.switchButton);
        sendButton = (Button) findViewById(R.id.sendbutton);
        imageView=(ImageView) findViewById(R.id.imageView);
        editText = (EditText) findViewById(R.id.editText);
        refreshButton = (ImageView)findViewById(R.id.refreshButton);
        adapter = new MyAdapter();
        listView.setAdapter(adapter);
        switchButton.setOnCheckedChangeListener(this);

        //监听列表元素点击事件
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                // 如果点击了设备列表元素
                // 停止搜索设备
                scanLeDevice(false);
                if(bluetoothGatt!=null)
                {
                    bluetoothGatt.disconnect();
                }
                // 获取到被点击的蓝牙设备
                device = deviceList.get(position);
                // 建立连接并设置回调函数
                bluetoothGatt = device.connectGatt(MainActivity.this, false, mGattCallback);
            }
        });
        // 风扇图片点击事件
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                imageViewClick();
            }
        });
        //刷新按钮点击事件
        refreshButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                refreshButtonClick();
            }
        });
        // 发送按钮监听事件
        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                sendbuttonClick();
            }
        });
    }

    //获取本地时间
    private String GetNowTime(){
        SimpleDateFormat formatter = new SimpleDateFormat ("HH:mm:ss");
        Date curDate = new Date(System.currentTimeMillis());//获取当前时间
        String str = formatter.format(curDate);
        return str;
    }

    //刷新按钮点击事件
    private void refreshButtonClick(){
        //断开连接
        if(bluetoothGatt!=null)
            bluetoothGatt.disconnect();
        if(deviceList!=null)
            deviceList.clear();
        if(data!=null)
            data.clear();
        adapter.notifyDataSetChanged();
        if(bluetoothAdapter != null)
        {
            if(bluetoothAdapter.isEnabled())
            {
                scanLeDevice(false);
                scanLeDevice(true);
            }
        }
    }

    // 风扇图片点击事件
    private void imageViewClick(){
        editText.setText(GetNowTime());
    }

    // 发送文字按钮点击事件
    private void sendbuttonClick(){
        sendbytes_count = 0;
        bytes_count = 0;
        try{
            //设置服务
            service = bluetoothGatt.getService(UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb"));
            // 设置特征值
            characteristic= service.getCharacteristic(UUID.fromString("0000fff6-0000-1000-8000-00805f9b34fb"));
            //获取字符串
            String str = editText.getText().toString();

            // 用于存放字模数据的数组
            byte[] my_data=null;
            // 判断文本输入框的内容不为空
            if(isconnected){
                // drawString方法将字符串转换成字模数据，只能用于汉字转换(16*16点阵的一个汉字 -> 32Byte)
                // 为方便接收数据包数据的起始和结束以三个连续的0xff
                my_data = drawString(str);
                bytes_count = my_data.length;
                //循环发送数据,一次最多发送20Byte
                for(int i=0;i<=my_data.length/20;i++){
                    if(i<my_data.length/20){
                        byte[] send_data=new byte[20];
                        System.arraycopy(my_data, i*20, send_data, 0, 20);
                        //将数据放置进特征中
                        characteristic.setValue(send_data);
                        //设置回复形式
                        characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
                        //开始写数据
                        bluetoothGatt.writeCharacteristic(characteristic);
                        SystemClock.sleep(100);
                    }
                    //最后一次循环判断：只有不能被20除尽时执行
                    else if(i==(my_data.length/20) && (my_data.length%20)!=0){
                        //创建一个20Byte的数组，用于存放最后一个数据包
                        byte[] send_data=new byte[20];
                        //填充结尾数据，多余部分不进行操作，默认值为0
                        System.arraycopy(my_data, i*20, send_data, 0, my_data.length%20);
                        //将指令放置进特征中
                        characteristic.setValue(send_data);
                        //设置回复形式
                        characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
                        //开始写数据
                        bluetoothGatt.writeCharacteristic(characteristic);
                    }
                }
            }
            else
            {
                Toast.makeText(this, "尚未连接", Toast.LENGTH_SHORT).show();
            }
        }
        catch (Exception ex) {
            new Thread(){
                public void run(){
                    Looper.prepare();//给当前线程初始化Looper
                    Toast.makeText(getApplicationContext(),"发送失败",0).show();//Toast初始化的时候会new Handler();无参构造默认获取当前线程的Looper，如果没有prepare过，则抛出题主描述的异常。上一句代码初始化过了，就不会出错。
                    Looper.loop();//这句执行，Toast排队show所依赖的Handler发出的消息就有人处理了，Toast就可以吐出来了。但是，这个Thread也阻塞这里了，因为loop()是个for (;;) ...
                }
            }.start();
                System.err.println("发送失败");
            }
        }

private boolean isconnected=false;
    private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        String TAG="Bluetooth";
        //连接状态改变的回调
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                //执行到这里其实蓝牙已经连接成功了
                isconnected=true;
                Log.e(TAG, "连接成功");
//                new Thread(){
//                    public void run(){
//                        Looper.prepare();//给当前线程初始化Looper
//                        Toast.makeText(getApplicationContext(),"蓝牙连接成功",0).show();//Toast初始化的时候会new Handler();无参构造默认获取当前线程的Looper，如果没有prepare过，则抛出题主描述的异常。上一句代码初始化过了，就不会出错。
//                        Looper.loop();//这句执行，Toast排队show所依赖的Handler发出的消息就有人处理了，Toast就可以吐出来了。但是，这个Thread也阻塞这里了，因为loop()是个for (;;) ...
//                    }
//                }.start();

                // 启动服务发现
                gatt.discoverServices();

            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                Log.e(TAG,"断开连接");
                bluetoothGatt.close();
            }
        }

       //发现服务的回调
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            //成功发现服务后可以调用相应方法得到该BLE设备的所有服务
            //并且打印每一个服务的UUID和每个服务下各个特征的UUID
            if (status == BluetoothGatt.GATT_SUCCESS) {
                supportedGattServices=bluetoothGatt.getServices();
                int service_count = supportedGattServices.size();
                if(service_count>0)
                new Thread(){
                    public void run(){
                        Looper.prepare();//给当前线程初始化Looper
                        Toast.makeText(getApplicationContext(),"蓝牙连接成功",0).show();//Toast初始化的时候会new Handler();无参构造默认获取当前线程的Looper，如果没有prepare过，则抛出题主描述的异常。上一句代码初始化过了，就不会出错。
                        Looper.loop();//这句执行，Toast排队show所依赖的Handler发出的消息就有人处理了，Toast就可以吐出来了。但是，这个Thread也阻塞这里了，因为loop()是个for (;;) ...
                    }
                }.start();
                Log.e(TAG, "成功发现"+service_count+"条服务,");
                }
                else{
                    Log.e(TAG, "服务发现失败，错误码为:" + status);
                }
            }

        //写操作的回调，发送数据成功时执行此方法
        public void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                sendbytes_count += characteristic.getValue().length;
                if(sendbytes_count >= bytes_count)
                {
                    new Thread(){
                        public void run(){
                            Looper.prepare();//给当前线程初始化Looper
                            Toast.makeText(getApplicationContext(),"写入成功"+sendbytes_count+"个字节",0).show();//Toast初始化的时候会new Handler();无参构造默认获取当前线程的Looper，如果没有prepare过，则抛出题主描述的异常。上一句代码初始化过了，就不会出错。
                            Looper.loop();//这句执行，Toast排队show所依赖的Handler发出的消息就有人处理了，Toast就可以吐出来了。但是，这个Thread也阻塞这里了，因为loop()是个for (;;) ...
                        }
                    }.start();
                    Log.e(TAG, "写入成功" +sendbytes_count+"个字节");
                }
            }
        }
        // 读操作的回调，当蓝牙接收到数据时执行此方法
        public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.e(TAG, "读取成功" +characteristic.getValue());
            }
        }

        //数据改变的回调（此处接收BLE设备数据）
        public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic) {

        }
    };


    private void initBT() {
        // 判断是否支持BLE特性
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            Toast.makeText(this, "该设备不支持BLE", Toast.LENGTH_SHORT).show();
            finish();
        }
        // 初始化蓝牙适配器
        BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        bluetoothAdapter = bluetoothManager.getAdapter();
        // 判断蓝牙是否开启，设定Switch的状态
        if (bluetoothAdapter.isEnabled()) {
            this.switchButton.setChecked(true);
        } else {
            this.switchButton.setChecked(false);
        }
    }

    //switchButton开关状态改变
    @Override
    public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
        switch (compoundButton.getId()) {
            case R.id.switchButton: {
                if (compoundButton.isChecked()) {
                    //打开蓝牙
                    openBT();
                } else {
                    //关闭蓝牙
                    bluetoothAdapter.disable();
                    while (bluetoothAdapter.isEnabled()) ;
                    Toast.makeText(this, "蓝牙已关闭", Toast.LENGTH_SHORT).show();

                }
            }

        }
    }

    //打开蓝牙
    private void openBT() {
            // 显示一个对话框要求用户授权启用蓝牙，并且自动开启300s的可见状态
            if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                enableBtIntent.setAction(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                enableBtIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            }
            Toast.makeText(this, "蓝牙已开启", Toast.LENGTH_SHORT).show();
            //等待开启
            while (!bluetoothAdapter.isEnabled());
            scanLeDevice(true);
    }

    private void scanLeDevice(final boolean enable) {
        BluetoothLeScanner leScanner = bluetoothAdapter.getBluetoothLeScanner();
        if (enable) {
            // 开启扫描
            mScanning=true;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
                // low api level
                bluetoothAdapter.startLeScan(mLeScanCallback);
            }
            else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
                    builder.setTitle("此应用需要定位权限");
                    builder.setMessage("请点击确定授予定位权限");
                    builder.setPositiveButton(android.R.string.ok, null);
                    builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
                        public static final int PERMISSION_REQUEST_COARSE_LOCATION = 3000;
                        @Override
                        public void onDismiss(DialogInterface dialog) {
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                                requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},PERMISSION_REQUEST_COARSE_LOCATION );
                            }
                        }
                    });
                    builder.show();
                }
                // high api level
                leScanner.startScan(scanCallback);
            }
        }
        else
        {
            //关闭扫描
            mScanning = false;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
                bluetoothAdapter.stopLeScan(mLeScanCallback);
            }
            else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                leScanner.stopScan(scanCallback);
            }

        }
    }
                    // 设备搜索回调接口,（android5.0之前的版本）
                    private BluetoothAdapter.LeScanCallback mLeScanCallback =
                    new BluetoothAdapter.LeScanCallback() {
                        @Override
                        public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
                            if(!deviceList.contains(device)){
                                deviceList.add(device);
                                dealBLE(device, rssi, scanRecord);
                            }
                        }
                    };
                    // 设备搜索回调接口,（android5.0之后的版本）
                    private ScanCallback scanCallback = new ScanCallback() {
                @Override
                public void onScanResult(int callbackType, ScanResult result) {
                    super.onScanResult(callbackType, result);
                    BluetoothDevice device=result.getDevice();
                    if(!deviceList.contains(device)){
                        deviceList.add(device);
                        dealBLE(device, result.getRssi(), result.getScanRecord().getBytes());
                    }
                }
            };

    void dealBLE(BluetoothDevice device, int rssi, byte[] data) {
        if (device == null) {
            return;
        }
        // deal ble info.
        String name = device.getName();
        String mac = device.getAddress();

        boolean exist = false;
        for (int i = 0; i < this.data.size(); i++) {
            if (this.data.get(i).mac.equals(mac)) {
                exist = true;
                break;
            }
        }
        if (!exist) {
            Item item = new Item(name, mac);
            this.data.add(item);
        }
        adapter.notifyDataSetChanged();
    }

    private static byte[] reverseBytes(byte[] a) {
        int len = a.length;
        byte[] b = new byte[len];
        for (int k = 0; k < len; k++) {
            b[k] = a[a.length - 1 - k];
        }
        return b;
    }

    // byte转十六进制字符串
    public static String bytes2HexString(byte[] bytes) {
        String ret = "";
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += hex.toUpperCase();
        }
        return ret;
    }


    /**
     * 得到一个字符串的长度,显示的长度,一个汉字或日韩文长度为1,英文字符长度为0.5
     *
     * @param
     *      s 需要得到长度的字符串
     * @return
     * 		得到的字符串长度
     */
    public static int getwidth(String s) {
        if (s == null) {
            return 0;
        }
        char[] c = s.toCharArray();
        int len = 0;
        for (int i = 0; i < c.length; i++) {
            if (isLetter(c[i])) {
                len += 1;
            } else {
                len += 2;
            }
        }
        return len;
    }
    /**
     * 判断一个字符是Ascill字符还是其它字符（如汉，日，韩文字符）
     *
     * @param c
     * @return boolean
     */
    public static boolean isLetter(char c) {
        int k = 0x80;
        return (c / k) == 0 ? true : false;
    }

    //打印输出字模，并转换成数组形式
    public byte[] drawString(String str) {

        byte[] get_data = null;
        byte[] data = null;
        int[] code = null;
        int byteCount;
        int lCount;
        int wordCount;
        int ascCount=0;
        //定义一个指定宽度的数组，数组长度为：字符宽度（像素）/8bit*16Byte
        //比如：1个16*16点阵中文字符，占用16(pix)/8*16=32字节
        //      3个英文字符/ASCII码：3*（8pix/8*16）=16个字节
        get_data=new byte[getwidth(str)*length_16];

        //中文计数
        wordCount=0;
        //英文/符号计数
        ascCount=0;
        //循环处理每个汉字或ASCII字符
        for (int i = 0; i < str.length(); i++) {
            //ASCII字符
            if (str.charAt(i) < 0x80) {
                //读取字模数据
                data = readASC(str.charAt(i));
                //为一个bool数组分配合适空间
                boolean[][] arr = new boolean[length_16][length_8];
                byteCount = 0;
                for (int line = 0; line < length_16; line++) {
                    lCount = 0;
                    for (int row = 0; row < length_8; row++) {
                        //将每一位数据0/1，用bool类型的二维数组表示出来
                        if (((data[byteCount] >> (7 - row)) & 0x1) == 1) {
                            arr[line][lCount] = true;
                            //System.out.print("*");
                        } else {
                            //System.out.print(" ");
                            arr[line][lCount] = false;
                        }
                        get_data[ascCount*length_16 + wordCount * length_32+lCount*2+line/length_8] |= ((arr[line][lCount]==true?1:0)<<(line%length_8));
                        //代表列自增
                        lCount++;
                    }
                    //字节或者行自增
                    byteCount++;
                }
                //一个ASCII码处理完成
              ascCount++;
            }
            //中文字符
            else {
                //获得区位码
                code = getByteCode(str.substring(i, i + 1));
                //原始字模数据
                data = read(code[0], code[1]);
                boolean[][] arr = new boolean[length_16][length_16];
                byteCount = 0;
                for (int line = 0; line < length_16; line++) {
                    lCount = 0;
                    for (int k = 0; k < length_2; k++) {
                        for (int j = 0; j < length_8; j++) {
                            //将每一位数据0/1，用bool类型的二维数组表示出来
                            if (((data[byteCount] >> (7 - j)) & 0x1) == 1) {
                                arr[line][lCount] = true;
                                //System.out.print("*");
                            } else {
                                //System.out.print(" ");
                                arr[line][lCount] = false;
                            }
                            //arr[][]二维数组为一个汉字横向取模得到的数据
                            //将arr[][]经过变换成竖向取模的数组get_data[][]
                            get_data[ascCount*length_16 + wordCount * length_32+lCount*2+line/length_8] |= ((arr[line][lCount]==true?1:0)<<(line%length_8));
                            //在同一行内，列序号加1（范围0-15）,lCount代表列
                            lCount++;
                        }
                        //处理完8个位，字节计数加1
                        byteCount++;
                    }
                    //处理完成一行数据，打印换行
                    System.out.println();
                }
                //一个汉字处理完成
                wordCount++;
            }
        }
        //打印输出处理后的字模数据
        //字符的个数
        for(int x=0;x<str.length();x++){
            //ASC
            if(str.charAt(x)<0x80){
                //行数
                for(int y=0;y<length_16;y++){
                    //列数
                    for(int z=0;z<length_8;z++){
                        byte a = (byte)((get_data[x*length_16+z*2+y/length_8]>>(y%length_8))&0x01);
                        boolean b=(a==1?true:false);
                        if(b==true){
                            System.out.print("*");
                        }
                        else {
                            System.out.print(" ");
                        }
                    }
                    //换行
                    System.out.println();
                }
                //换字
                System.out.println();
            }
            //中文字符
            else {
                //行数
                for(int y=0;y<length_16;y++){
                    //列数
                    for(int z=0;z<length_16;z++){
                        byte a = (byte)((get_data[x*length_32+z*2+y/length_8]>>(y%length_8))&0x01);
                        boolean b=(a==1?true:false);
                        if(b==true){
                            System.out.print("*");
                        }
                        else {
                            System.out.print(" ");
                        }
                    }
                    //换行
                    System.out.println();
                }
                //换字
                System.out.println();
            }
        }

        byte[] return_data=new byte[get_data.length+6];
        for(int i=0;i<3;i++){
            return_data[i]='{';     // 起始位置放3个'{'
            return_data[get_data.length+5-i]='}';   // 结束位置放3个'}'
        }
        System.arraycopy(get_data, 0, return_data, 3, get_data.length);
        return return_data;
    }

    /*********************
     *取ASCII字符字模函数
     ********************/
    protected byte[] readASC(char c) {
        byte[] data = null;
        try{
            int addr = (c)*0x10;
            InputStream in = getResources().openRawResource(R.raw.asc16);
            //地址偏移量addr
            in.skip(addr);
            data = new byte[length_16];
            in.read(data, 0, length_16);
            in.close();
        }
        catch (Exception ex){
            System.err.println("SORRY,THE FILE CAN'T BE READ");
        }
        return data;
    }
    /**
    *取单个汉字字模函数
    */
    protected byte[] read(int areaCode, int posCode) {
        byte[] data = null;
        try {
            int area = areaCode - 0xa0;
            int pos = posCode - 0xa0;
            InputStream in = getResources().openRawResource(R.raw.hzk16s);
            long offset = length_32 * ((area - 1) * 94 + pos - 1);
            in.skip(offset);
            data = new byte[length_32];
            in.read(data, 0, length_32);
            in.close();
        } catch (Exception ex) {
            System.err.println("SORRY,THE FILE CAN'T BE READ");
        }
        return data;

    }
    protected int[] getByteCode(String str) {
        int[] byteCode = new int[2];
        try {
            byte[] data = str.getBytes("GB2312");
            byteCode[0] = data[0] < 0 ? 256 + data[0] : data[0];
            byteCode[1] = data[1] < 0 ? 256 + data[1] : data[1];
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return byteCode;
    }

    /**
     * ATTENTION: This was auto-generated to implement the App Indexing API.
     * See https://g.co/AppIndexing/AndroidStudio for more information.
     */
    public Action getIndexApiAction() {
        Thing object = new Thing.Builder()
                .setName("Main Page") // TODO: Define a title for the content shown.
                // TODO: Make sure this auto-generated URL is correct.
                .setUrl(Uri.parse("http://[ENTER-YOUR-URL-HERE]"))
                .build();
        return new Action.Builder(Action.TYPE_VIEW)
                .setObject(object)
                .setActionStatus(Action.STATUS_TYPE_COMPLETED)
                .build();
    }

    @Override
    public void onStart() {
        super.onStart();
        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        client.connect();
        AppIndex.AppIndexApi.start(client, getIndexApiAction());
        if(bluetoothAdapter.isEnabled()){
            scanLeDevice(true);
        }

    }

    @Override
    public void onStop() {
        super.onStop();
        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        AppIndex.AppIndexApi.end(client, getIndexApiAction());
        client.disconnect();
        if(bluetoothAdapter.isEnabled()){
            scanLeDevice(false);
        }
    }
    @Override
    public void onRestart(){
        super.onRestart();
        if(bluetoothAdapter.isEnabled()){
            scanLeDevice(true);
        }


    }

    class MyAdapter extends BaseAdapter {

        LayoutInflater inflater;

        public MyAdapter() {
            inflater = LayoutInflater.from(MainActivity.this);
        }

        @Override
        public int getCount() {
            if (data == null) {
                return 0;
            }
            return data.size();
        }

        @Override
        public Object getItem(int position) {

            return data.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder = null;
            if (convertView == null) {
                viewHolder = new ViewHolder();
                convertView = inflater.inflate(R.layout.list_item, null);
                viewHolder.nameTextView = (TextView) convertView.findViewById(R.id.device_name);
                viewHolder.macTextView = (TextView) convertView.findViewById(R.id.device_address);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
            Item item = data.get(position);
            if (item.name == null || item.name.length() == 0) {
                viewHolder.nameTextView.setText("no name");
            } else {
                viewHolder.nameTextView.setText(item.name);
            }

            viewHolder.macTextView.setText(item.mac);
            return convertView;
        }
    }

    class Item {
        String name;
        String mac;

        public Item(String name, String mac) {
            this.name = name;
            this.mac = mac;
        }
    }

    class ViewHolder {
        TextView nameTextView;
        TextView macTextView;
    }
}
